package com.itheima.appserver.service;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.config.annotation.Reference;

import com.itheima.appserver.interceptor.UserThreadLocal;
import com.itheima.commons.model.domain.Question;
import com.itheima.commons.model.domain.User;
import com.itheima.commons.model.domain.UserInfo;
import com.itheima.commons.model.mongo.Report;
import com.itheima.commons.model.mongo.Soul;
import com.itheima.commons.model.mongo.SoulOption;
import com.itheima.commons.model.mongo.SoulQuestion;
import com.itheima.commons.model.vo.*;
import com.itheima.dubbo.interfaces.SoulApi;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SoulService {

    @Reference
    private SoulApi soulApi;

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 测灵魂-问卷列表
     *
     * @return
     */
    public List<SoulVo> querySoulQustionsList() {

        User user = UserThreadLocal.get();
        List<Soul> soulList = soulApi.querySoulList(user.getId());
        List<SoulVo> soulVoList = new ArrayList<>();

        if (CollectionUtils.isEmpty(soulList)) {
            //为用户生成3套题目
            //先随机拿到题目 根据type
            for (int i = 1; i <= 3; i++) {
                List<SoulQuestion> questionList = soulApi.queryQuestions(i);
                Collections.shuffle(questionList);
                questionList = questionList.stream().limit(10).collect(Collectors.toList());
                //封装成对应的 soul
                Soul soul = this.creatSoul(questionList, i);
                //保存到mongodb
                soulApi.saveSoul(soul);
                soulList.add(soul);
            }
        }

        for (Soul soul : soulList) {
            SoulVo soulVo = new SoulVo();

            soulVo.setId(String.valueOf(soul.getId()));
            soulVo.setCover(soul.getCover());
            soulVo.setIsLock(soul.getIsLock());
            soulVo.setName(soul.getName());
            soulVo.setLevel(soul.getLevel());
            soulVo.setStar(soul.getStar());
            //结果报告的 id
            soulVo.setReportId(soulApi.queryReportId(soulVo.getId()));

            //获取到所有的题目
            List<SoulQuestion> questionList = soulApi.queryQuestionList(soul.getQuestionIds());
            List<SoulQuestionVo> questions = new ArrayList<>();
            for (SoulQuestion question : questionList) {
                SoulQuestionVo soulQuestionVo = new SoulQuestionVo();
                soulQuestionVo.setId(String.valueOf(question.getId()));
                soulQuestionVo.setQuestion(question.getQuestion());

//                List<SoulOption> options = question.getOptions();
                List<SoulOption> options = soulApi.queryOptionList(question.getOptions());

                ArrayList<OptionVo> vos = new ArrayList<>();
                for (SoulOption option : options) {
                    OptionVo optionsVo = new OptionVo();
                    optionsVo.setId(option.getId().toHexString());
                    optionsVo.setOption(option.getOption());
                    vos.add(optionsVo);
                }
                soulQuestionVo.setOptions(vos);
                questions.add(soulQuestionVo);
            }
            soulVo.setQuestions(questions);
            soulVoList.add(soulVo);
        }

        return soulVoList;
    }

    private Soul creatSoul(List<SoulQuestion> questionList, int type) {
        User user = UserThreadLocal.get();
        Soul soul = new Soul();

        List<ObjectId> questionIds = new ArrayList<>();
        for (SoulQuestion question : questionList) {
            questionIds.add(question.getId());
        }
        soul.setId(new ObjectId());
        soul.setQuestionIds(questionIds);
        soul.setUserId(user.getId());
        if (1 == type) {
            soul.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/qn_cover_01.png");
            soul.setIsLock(0);
            soul.setLevel("初级");
            soul.setName("初级灵魂题");
            soul.setStar(2);
        } else if (2 == type) {
            soul.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/qn_cover_02.png");
            soul.setIsLock(1);
            soul.setLevel("中级");
            soul.setName("中级灵魂题");
            soul.setStar(3);
        } else {
            soul.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/qn_cover_03.png");
            soul.setIsLock(1);
            soul.setLevel("高级");
            soul.setName("高级灵魂题");
            soul.setStar(5);
        }
        return soul;
    }

    /**
     * 测灵魂-提交问卷答案
     *
     * @param param
     * @return
     */
    public String SaveSoulAnswer(Map<String, List<AnswerVo>> param) {

        List<AnswerVo> answers = param.get("answers");
        int score = 0;

        //查询所有的 题目及选项
        SoulQuestion question = null;
        for (AnswerVo answer : answers) {
            question = soulApi.queryQuestion(answer.getQuestionId());
//            List<SoulOption> options = question.getOptions();
            List<SoulOption> options = soulApi.queryOptionList(question.getOptions());
            for (SoulOption option : options) {
                if (answer.getOptionId().equals(option.getId().toString())) {
                    //计算总分
                    score += option.getScore();
                    break;
                }
            }
        }
        Integer type = question.getType();
        String level = "";
        if (1 == type) {
            level = "初级";
        } else if (2 == type) {
            level = "中级";
        } else {
            level = "高级";
        }
        //根据总分 生成对应的报告
        Report report = this.result(score, level);
        //返回report主键
        return soulApi.saveReport(report);
    }


    private Report result(int score, String level) {
        User user = UserThreadLocal.get();

        //获取 soluId
        String soulId = soulApi.querySoulId(level, user.getId());

        Report report = new Report();
        report.setSoulId(new ObjectId(soulId));
        List<Dimensions> list = new ArrayList<>();

        if (score <= 20) {
            report.setConclusion("猫头鹰：他们的共同特质为重计划、条理、细节精准。在行为上，表现出喜欢理性思考与分析、较重视制度、结构、规范。他们注重执行游戏规则、循规蹈矩、巨细靡遗、重视品质、敬业负责。");
            report.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/owl.png");
            report.setUserId(user.getId());

            list.add(new Dimensions("内向", "75%"));
            list.add(new Dimensions("判断", "80%"));
            list.add(new Dimensions("可靠", "60%"));
            list.add(new Dimensions("理性", "75%"));

            report.setDimensions(list);
        } else if (20 < score && score <= 40) {

            report.setConclusion("白兔型：平易近人、敦厚可靠、避免冲突与不具批判性。在行为上，表现出不慌不忙、冷静自持的态度。他们注重稳定与中长程规划，现实生活中，常会反思自省并以和谐为中心，即使面对困境，亦能泰然自若，从容应付。");
            report.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/rabbit.png");
            report.setUserId(user.getId());

            list.add(new Dimensions("稳定", "70%"));
            list.add(new Dimensions("友善", "75%"));
            list.add(new Dimensions("耐心", "80%"));
            list.add(new Dimensions("可靠", "80%"));

            report.setDimensions(list);
        } else if (41 < score && score <= 55) {

            report.setConclusion("狐狸型 ：人际关系能力极强，擅长以口语表达感受而引起共鸣，很会激励并带动气氛。他们喜欢跟别人互动，重视群体的归属感，基本上是比较「人际导向」。由于他们富同理心并乐于分享，具有很好的亲和力，在服务业、销售业、传播业及公共关系等领域中，狐狸型的领导者都有很杰出的表现。");
            report.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/fox.png");
            report.setUserId(user.getId());

            list.add(new Dimensions("外向", "70%"));
            list.add(new Dimensions("自信", "75%"));
            list.add(new Dimensions("乐观", "80%"));
            list.add(new Dimensions("热情", "60%"));

            report.setDimensions(list);
        } else if (56 <= score) {
            report.setConclusion("狮子型：性格为充满自信、竞争心强、主动且企图心强烈，是个有决断力的领导者。一般而言，狮子型的人胸怀大志，勇于冒险，看问题能够直指核心，并对目标全力以赴。\n" +
                    "他们在领导风格及决策上，强调权威与果断，擅长危机处理，此种性格最适合开创性与改革性的工作。");
            report.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/lion.png");
            report.setUserId(user.getId());

            list.add(new Dimensions("外向", "80%"));
            list.add(new Dimensions("判断", "85%"));
            list.add(new Dimensions("抽象", "80%"));
            list.add(new Dimensions("理性", "90%"));

            report.setDimensions(list);
        }

        return report;
    }

    /**
     * 测灵魂-查看结果
     *
     * @param reportId
     * @return
     */
    public ReportVo queryReport(String reportId) {

        ReportVo reportVo = new ReportVo();
        Report report = soulApi.queryReport(reportId);
        if (null == report) {
            return reportVo;
        }

        reportVo.setConclusion(report.getConclusion());
        reportVo.setCover(report.getCover());
        reportVo.setDimensions(report.getDimensions());

        //查询与你类似的人
        List<Report> reportList = soulApi.querySimilarYou(report);
        if (CollectionUtils.isEmpty(reportList)) {
            reportVo.setSimilarYou(null);
        }
        Set<Long> userIds = new HashSet<>();
        for (Report rp : reportList) {
            //排除自己
            if (report.getUserId().equals(rp.getUserId())) {
                continue;
            }
            userIds.add(rp.getUserId());
        }
        //截取 最多10个用户进行推荐
        int recommendCount = Math.min(10, userIds.size());
        userIds = userIds.stream().limit(recommendCount).collect(Collectors.toSet());

        List<UserInfo> userInfos = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(userIds)) {
            userInfos = userInfoService.queryUserInfoList(userIds);
        }

        List<SimilarYou> similarList = new ArrayList<>();

        for (UserInfo userInfo : userInfos) {
            SimilarYou similarYou = new SimilarYou();

            similarYou.setId(userInfo.getId());
            similarYou.setAvatar(userInfo.getLogo());

            similarList.add(similarYou);
        }
        reportVo.setSimilarYou(similarList);

        return reportVo;
    }


}
